using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using FreeLancer.HRB.Domains;
using FreeLancer.HRB.Services;
using DevExpress.Web.ASPxUploadControl;
using FreeLancer.HRB.Core;
using DevExpress.Web.ASPxClasses;
using FreeLancer.HRB.Core.Services;
using System.Xml;

namespace FreeLancer.HRB.WebApp.Admin.Pages
{
  public partial class EditEvent : System.Web.UI.Page
  {
    #region Private Members

    private ImagesService _imagesService = GlobalCache.ImagesService;
    private EventsService _eventsService = GlobalCache.EventsService;
    private TList<Images> _images = new TList<Images>();
    private FreeLancer.HRB.Domains.Events _event = null;
    private int _languageId;

    private const string Delete = "Delete";
    private const string Add = "Add";
    private const string Update = "Update";
    private const string Load = "Load";
    private const string EventImagePath = "~/Images/EventImages/";

    #endregion

    #region Page Events

    protected void Page_Init(object sender, EventArgs e)
    {
      SessionWrapper.SetSession(Session);

      LoadLanguage();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
      LoadEvent();
      if(!IsPostBack)
        InitializePageContent();

      if (_event != null)
        AllowEditImages(true);
      else
        AllowEditImages(false);

      lblErrorUpdateFailed.Visible = false;
      lblErrorLoadFailed.Visible = false;
      lblErrorDeleteFailed.Visible = false;
    }

    #endregion

    #region Control Events

    protected void cboLanguage_SelectedIndexChanged(object sender, EventArgs e)
    {
    }

    //protected void cboEvents_SelectedIndexChanged(object sender, EventArgs e)
    //{
    //  if (cboEvents.SelectedIndex == 0)
    //    Response.Redirect("Events.aspx");
    //  else
    //    Response.Redirect("Events.aspx?Id=" + cboEvents.SelectedValue);
    //}

    protected void btnSave_Click(object sender, EventArgs e)
    {
      GetEventContent();

      bool flagNew = _event.IsNew;

      try
      {
        using (ConnectionScope.CreateTransaction())
        {
          _eventsService.Save(_event);
          if (ConnectionScope.Complete())
          {
            AllowEditImages(true);

            cboLanguage.Enabled = false;
            cboLanguage.SelectedValue = _languageId.ToString();
          }
          else
          {
            LoggingService.LogError("Admin-Edit Event Page", "Can not complete transaction when saving Event.",
              null, LoggingService.DefaultCategory, true);

            lblErrorUpdateFailed.Visible = true;
          }
        }
      }
      catch (Exception ex)
      {
        LoggingService.LogCritical("Admin-Edit Event Page", "Can not save Event.", ex,
              LoggingService.DefaultCategory, true);

        lblErrorUpdateFailed.Visible = true;
      }

      if (flagNew)
      {
        Response.Redirect("EditEvent.aspx?Id=" + _event.EventId);
      }
      else
      {
        ASPxDataView.DataBind();
      }
    }

    protected void btnDelete_Click(object sender, EventArgs e)
    {
      if (_event != null)
      {
        try
        {
          using (ConnectionScope.CreateTransaction())
          {
            _eventsService.Delete(_event);

            if (ConnectionScope.Complete())
            {
              Response.Redirect("EditEvent.aspx");
            }
            else
            {
              LoggingService.LogError("Admin-Edit Event Page", "Can not complete transaction when deleting Event.",
              null, LoggingService.DefaultCategory, true);

              lblErrorDeleteFailed.Visible = true;
            }
          }
        }
        catch (Exception ex)
        {
          LoggingService.LogCritical("Admin-Edit Event Page", "Can not delete Event.", ex,
              LoggingService.DefaultCategory, true);

          lblErrorDeleteFailed.Visible = true;
        }
      }
    }

    #endregion

    #region Upload

    protected void ASPxUploadControl_FileUploadComplete(object sender, FileUploadCompleteEventArgs e)
    {
      if (e.IsValid)
      {
        string path = Server.MapPath(EventImagePath);
        DateTime now = DateTime.Now;
        path = path + now.ToString("yyyy_MM_dd_hh_mm_ss") + "_" + ASPxUploadControl.FileName;

        ASPxUploadControl.SaveAs(path, true);

        e.CallbackData = now.ToString("yyyy_MM_dd_hh_mm_ss") + "_" + ASPxUploadControl.FileName;
      }
    }

    #endregion

    #region Dataview

    protected void ASPxDataView_OnCustomCallback(object sender, CallbackEventArgsBase e)
    {
      ExecuteCommand(e.Parameter);
    }

    #endregion

    #region Load Image Information

    protected void ASPxCallbackPanel_OnCallback(object sender, CallbackEventArgsBase e)
    {
      ExecuteCommand(e.Parameter);
    }

    #endregion

    #region Save Image by Post back

    protected void ASPxButtonUpdate_OnClick(object sender, EventArgs e)
    {
      if (_images.Count > 0)
      {
        ASPxDataView.DataSource = _images;
        ASPxDataView.DataBind();
        return;
      }

      bool flagSuccess = false;
      Images image = new Images();

      try
      {
        using (ConnectionScope.CreateTransaction())
        {
          if (image != null)
          {
            image.Title = ASPxTextBoxImageTitle.Text;
            image.Description = ASPxMemoImageDescription.Text;
            image.LinkPage = ASPxTextBoxImageLink.Text.Replace('[', ':');

            if (!string.IsNullOrEmpty(ASPxTextBoxImageName.Text))
              image.Path = ASPxTextBoxImageName.Text;
            else
              image.Path = string.Empty;

            image.EventId = _event.EventId;
            image.LanguageId = _languageId;

            _imagesService.Save(image);
          }

          flagSuccess = ConnectionScope.Complete();
          if (flagSuccess)
          {
            _images.Add(image);
            ASPxDataView.DataSource = _images;
            ASPxDataView.DataBind();
          }
        }
      }
      catch (Exception ex)
      {
        LoggingService.LogCritical("Admin-Edit Event Page", "Can not add Image.", ex,
              LoggingService.DefaultCategory, true);
      }
    }

    #endregion

    #region Page Processing

    /// <summary>
    /// Initialize language to combobox
    /// </summary>
    private void LoadLanguage()
    {
      int total = 0;
      LanguagesService languageService = new LanguagesService();
      TList<Languages> languages = languageService.GetPaged("IsActive='True'", string.Empty, 0, 3, out total);
      cboLanguage.DataSource = languages;
      cboLanguage.DataTextField = "Name";
      cboLanguage.DataValueField = "LanguageID";
      cboLanguage.DataBind();
    }

    private void LoadEvent()
    {
      string eventId = Request["Id"];
      if (!string.IsNullOrEmpty(eventId))
      {
        if (eventId.Length == 36)
        {
          try
          {
            _languageId = SessionWrapper.LanguageId;
            if ((_languageId == 0) && (cboLanguage.Items.Count > 0))
              _languageId = int.Parse(cboLanguage.Items[0].Value);

            _event = _eventsService.GetByEventIdLanguageId(new Guid(eventId), _languageId);
            _images = _imagesService.GetByEventIdLanguageId(_event.EventId, _languageId);
            if (_event != null)
            {
              //cboEvents.SelectedIndex = cboEvents.Items.IndexOf(
              //  cboEvents.Items.FindByValue(_event.EventId.ToString()));
            }
          }
          catch (Exception e)
          {
            LoggingService.LogCritical("Admin-Edit Event Page", "Can not load data for Event",
              e, LoggingService.DefaultCategory, true);
          }
        }
      }

      if (_images.Count > 0)
        ASPxButtonUpdate.AutoPostBack = false;
      else
        ASPxButtonUpdate.AutoPostBack = true;

      ASPxDataView.DataSource = _images;
      ASPxDataView.DataBind();
    }

    private void InitializePageContent()
    {
      if (_event != null)
      {
        txtTitle.Text = _event.Title;
        txtDescription.Text = _event.Description;
        btnDelete.Enabled = true;

        lblTime.Text = _event.DateModified.ToString();
        chkIsPublished.Checked = _event.IsPublished;

        lblUpdateAt.Visible = true;
        lblTime.Visible = true;

        cboLanguage.SelectedValue = _languageId.ToString();
        cboLanguage.Enabled = false;
      }
      else
      {
        btnDelete.Enabled = false;

        //New event
        lblUpdateAt.Visible = false;
        lblTime.Visible = false;

        cboLanguage.Enabled = true;
      }

      
    }

    /// <summary>
    /// Put data to Post
    /// </summary>
    private void GetEventContent()
    {
      LoadEvent();

      DateTime now = DateTime.Now;
      if (_event == null)
      {
        _event = new FreeLancer.HRB.Domains.Events();
        _event.EventId = Guid.NewGuid();
        _event.LanguageId = int.Parse(cboLanguage.SelectedValue);
        _event.DateCreated = now;  
      }

      _event.DateModified = now;
      _event.IsPublished = chkIsPublished.Checked;
      _event.Title = txtTitle.Text;
      _event.Description = txtDescription.Text;
    }

    #region Image Processing Commands

    private void ExecuteCommand(string parameter)
    {
      string[] parameters = parameter.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

      bool flagSuccess = false;

      if (parameters.Length > 1)
      {
        switch (parameters[1])
        {
          case Load:
            flagSuccess = LoadImage(parameters[0]);
            break;
          case Add:
            flagSuccess = AddImage(parameters);
            break;
          case Update:
            flagSuccess = UpdateImage(parameters);
            break;
          case Delete:
            flagSuccess = DeleteImage(parameters[0]);
            break;
        }
      }

      if (flagSuccess)
      {
        ASPxDataView.DataSource = _images;
        ASPxDataView.DataBind();
      }
    }

    private bool DeleteImage(string imageId)
    {
      bool flagSuccess = false;
      Images image = _images.Find(ImagesColumn.ImageId, int.Parse(imageId));
      try
      {
        using (ConnectionScope.CreateTransaction())
        {
          if (image != null)
          {
            _images.Remove(image);
            if (image.ImageId > 0)
              _imagesService.Delete(image);
          }
          else
          {
            if (int.Parse(imageId) > 0)
              _imagesService.Delete(int.Parse(imageId));
          }

          flagSuccess = ConnectionScope.Complete();
        }
      }
      catch (Exception ex)
      {
        LoggingService.LogCritical("Admin-Edit Event Page", "Can not delete Image.", ex,
              LoggingService.DefaultCategory, true);
      }
      return flagSuccess;
    }

    private bool UpdateImage(string[] parameters)
    {
      bool flagSuccess = false;
      Images image = _images.Find(ImagesColumn.ImageId, int.Parse(parameters[0]));

      XmlDocument doc = new XmlDocument();
      doc.LoadXml(parameters[2]);
      XmlElement root = doc.DocumentElement;

      try
      {
        using (ConnectionScope.CreateTransaction())
        {
          if (image != null)
          {
            image.Title = root.ChildNodes[0].Attributes["Text"].Value;
            image.Description = root.ChildNodes[1].Attributes["Text"].Value;
            image.LinkPage = root.ChildNodes[2].Attributes["Text"].Value.Replace('[', ':');

            if (!string.IsNullOrEmpty(root.ChildNodes[3].Attributes["Text"].Value))
              image.Path = root.ChildNodes[3].Attributes["Text"].Value;

            _imagesService.Save(image);
          }

          flagSuccess = ConnectionScope.Complete();
        }
      }
      catch (Exception ex)
      {
        LoggingService.LogCritical("Admin-Edit Event Page", "Can not update Image.", ex,
              LoggingService.DefaultCategory, true);
      }
      return flagSuccess;
    }

    private bool AddImage(string[] parameters)
    {
      bool flagSuccess = false;
      Images image = new Images();

      XmlDocument doc = new XmlDocument();
      doc.LoadXml(parameters[2]);
      XmlElement root = doc.DocumentElement;

      try
      {
        using (ConnectionScope.CreateTransaction())
        {
          if (image != null)
          {
            image.Title = root.ChildNodes[0].Attributes["Text"].Value;
            image.Description = root.ChildNodes[1].Attributes["Text"].Value;
            image.LinkPage = root.ChildNodes[2].Attributes["Text"].Value.Replace('[', ':');

            if (!string.IsNullOrEmpty(root.ChildNodes[3].Attributes["Text"].Value))
              image.Path = root.ChildNodes[3].Attributes["Text"].Value;

            image.EventId = _event.EventId;
            image.LanguageId = _languageId;
            _imagesService.Save(image);
          }

          flagSuccess = ConnectionScope.Complete();
          if (flagSuccess)
            _images.Add(image);
        }
      }
      catch (Exception ex)
      {
        LoggingService.LogCritical("Admin-Edit Event Page", "Can not add Image.", ex,
              LoggingService.DefaultCategory, true);
      }
      return flagSuccess;
    }

    private bool LoadImage(string imageId)
    {
      bool flagSuccess = false;
      Images image = _images.Find(ImagesColumn.ImageId, int.Parse(imageId));

      if (image != null)
      {
        ASPxMemoImageDescription.Text = image.Description;
        ASPxTextBoxImageLink.Text = image.LinkPage;
        ASPxTextBoxImageTitle.Text = image.Title;
        ASPxImage.ImageUrl = EventImagePath + image.Path;

        flagSuccess = true;
      }

      return flagSuccess;
    }

    #endregion

    private void AllowEditImages(bool isAllowed)
    {
      ASPxCallbackPanel.Enabled = isAllowed;
      ASPxDataView.Enabled = isAllowed;
    }

    #endregion
  }
}
